package com.park.wx;

import com.park.wx.util.CommonUtil;
import com.park.wx.pojo.AccessToken;
import com.park.wx.pojo.JsapiTicket;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;


public class WeiXinConnector {

	private static org.slf4j.Logger log = LoggerFactory.getLogger(CommonUtil.class);

	public static final String CORP_ID = ""; //;"wx1cfcdf89afb2c7c9";//企业号的CorpID
	
	public static final String APP_ID = "wxbaf413ee5e71cbbb"; //"wx48ce782a498f4a72"; //"wxbaf413ee5e71cbbb"; //"wx86c89d3d834ee891";//"wx3b705c91dccc6f35";//"wx86c89d3d834ee891";//"wx48ce782a498f4a72";//"wx86c89d3d834ee891";//APP_ID

	public static final String SECRET = "a5236c1acad6735e140c5cf1990e09e8"; //"3430b2d2fe0c03a3fca68b38fcc96998"; //"a5236c1acad6735e140c5cf1990e09e8"; //"f0ea47515f733c537d196c4017a51c6e";//Secret

	public static final String MCH_ID = "1481557762"; //"1391210602";//商户号mch_id
	
	public static final String KEY = "19930824199308241993082419930ZPX"; //"d58g3jkri91qawpdnv74dn3e0mnh4de2";//商户号mch_id

	public static final String DOMIAN = "http://www.xingzuo99.cc"; //"http://123.56.219.11/m";//"http://tuhao.viphk.ngrok.org";


	static AccessToken token = null;
	static JsapiTicket jsapiTicket = null;
	static long tokenTime = System.currentTimeMillis();
	static long jsapiTicketTime = System.currentTimeMillis();

	// 凭证获取（GET）
	public final static String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";

	//授权登录（GET）
	public final static String oauth2_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";

	//分享获取jsapi_ticket
	public final static String ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
	/**
	 * 发送https请求
	 *
	 * @param requestUrl
	 *            请求地址
	 * @param requestMethod
	 *            请求方式（GET、POST）
	 * @param outputStr
	 *            提交的数据
	 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
	 */
	public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
		JSONObject jsonObject = null;
		try {
			// 创建SSLContext对象，并使用我们指定的信任管理器初始化
			/*TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory ssf = sslContext.getSocketFactory();*/

			URL url = new URL(requestUrl);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			//conn.setSSLSocketFactory(ssf);

			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			// 设置请求方式（GET/POST）
			conn.setRequestMethod(requestMethod);

			// 当outputStr不为null时向输出流写数据
			if (null != outputStr) {
				OutputStream outputStream = conn.getOutputStream();
				// 注意编码格式
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}

			// 从输入流读取返回内容
			InputStream inputStream = conn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(
					inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(
					inputStreamReader);
			String str = null;
			StringBuffer buffer = new StringBuffer();
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}

			// 释放资源
			bufferedReader.close();
			inputStreamReader.close();
			inputStream.close();
			inputStream = null;
			conn.disconnect();
			jsonObject = JSONObject.fromObject(buffer.toString());
		} catch (ConnectException ce) {
			log.error("连接超时：{}", ce);
		} catch (Exception e) {
			log.error("https请求异常：{}", e);
		}
		return jsonObject;
	}

	/**
	 * 获取接口访问凭证
	 *
	 * @param appid
	 *            凭证
	 * @param appsecret
	 *            密钥
	 * @return
	 */
	public static AccessToken getToken(String appid, String appsecret) {
		if(token == null || ((System.currentTimeMillis() - tokenTime) / 1000) > 7000) { //7200秒过期
			String requestUrl = token_url.replace("APPID", appid).replace(
					"APPSECRET", appsecret);
			// 发起GET请求获取凭证
			JSONObject jsonObject = httpsRequest(requestUrl, "GET", null);

			if (null != jsonObject) {
				try {
					token = new AccessToken();
					token.setToken(jsonObject.getString("access_token"));
					token.setExpiresIn(jsonObject.getInt("expires_in"));
				} catch (JSONException e) {
					token = null;
					// 获取token失败
					log.error("获取token失败 errcode:{} errmsg:{}",
							jsonObject.getInt("errcode"),
							jsonObject.getString("errmsg"));
				}
			}
			tokenTime = System.currentTimeMillis();
		}
		return token;
	}

	/**
	 * 获取JS接口访问凭证
	 */
	public static JsapiTicket getJsapiTicket(String accessToken) {
		if(jsapiTicket == null || ((System.currentTimeMillis() - jsapiTicketTime) / 1000) > 7000) { //7200秒过期
			String requestUrl = ticket_url.replace("ACCESS_TOKEN", accessToken);
			// 发起GET请求获取凭证
			JSONObject jsonObject = httpsRequest(requestUrl, "GET", null);

			if (null != jsonObject) {
				try {
					jsapiTicket = new JsapiTicket();
					jsapiTicket.setTicket(jsonObject.getString("ticket"));
					jsapiTicket.setExpiresIn(jsonObject.getInt("expires_in"));
				} catch (JSONException e) {
					token = null;
					// 获取token失败
					log.error("获取token失败 errcode:{} errmsg:{}",
							jsonObject.getInt("errcode"),
							jsonObject.getString("errmsg"));
				}
			}
			jsapiTicketTime = System.currentTimeMillis();
		}
		return jsapiTicket;
	}

	/**
	 * (微信)获取签名signature
	 */
	public static Map<String, String> getTargetMap(JsapiTicket jsapiTicket, String currentUrl){
		Map<String, String> valueMap = new LinkedHashMap<String, String>();
		valueMap.put("jsapi_ticket", jsapiTicket.getTicket());
		valueMap.put("noncestr", UUID.randomUUID().toString());
		valueMap.put("timestamp", Long.toString(System.currentTimeMillis() / 1000));
		valueMap.put("url", currentUrl);

		StringBuffer strBuf = new StringBuffer();
		Iterator it = valueMap.entrySet().iterator();
		while(it.hasNext()){
			Map.Entry entry = (Map.Entry) it.next();
			strBuf.append("&" + entry.getKey() + "=" + entry.getValue());
		}
		MessageDigest md = null;
		try {
			md = MessageDigest.getInstance("SHA-1");
		} catch (NoSuchAlgorithmException e) {
		}
		md.reset();
		try {
			md.update(strBuf.toString().substring(1).getBytes("UTF-8"));
		} catch (UnsupportedEncodingException e) {
		}
		String signature = bytesToHexString(md.digest());
		valueMap.put("signature", signature);
		return valueMap;
	}

	/**
	 *
	 * byte转为String
	 * @param src
	 * @return
	 * @date 2016年01月6日下午4:48:25
	 */
	public static String bytesToHexString(byte[] src){
		StringBuilder stringBuilder = new StringBuilder("");
		if (src == null || src.length <= 0) {
			return null;
		}
		for (int i = 0; i < src.length; i++) {
			int v = src[i] & 0xFF;
			String hv = Integer.toHexString(v);
			if (hv.length() < 2) {
				stringBuilder.append(0);
			}
			stringBuilder.append(hv);
		}
		return stringBuilder.toString();
	}

	/**
	 * URL编码（utf-8）
	 *
	 * @param source
	 * @return
	 */
	public static String urlEncodeUTF8(String source) {
		String result = source;
		try {
			result = java.net.URLEncoder.encode(source, "utf-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 根据内容类型判断文件扩展名
	 *
	 * @param contentType 内容类型
	 * @return
	 */
	public static String getFileExt(String contentType) {
		String fileExt = "";
		if ("image/jpeg".equals(contentType))
			fileExt = ".jpg";
		else if ("audio/mpeg".equals(contentType))
			fileExt = ".mp3";
		else if ("audio/amr".equals(contentType))
			fileExt = ".amr";
		else if ("video/mp4".equals(contentType))
			fileExt = ".mp4";
		else if ("video/mpeg4".equals(contentType))
			fileExt = ".mp4";
		return fileExt;
	}

	public static String getKey() {
		return KEY;
	}

	public static String getSecret() {
		return SECRET;
	}
	
}
